import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:mahjong/const/MahjongConst.dart';
import 'package:mahjong/const/MahjongSystemConst.dart';
import 'package:mahjong/entity/MessageContext.dart';
import 'package:mahjong/entity/card/MahjongCardEntity.dart';
import 'package:mahjong/entity/mahjong/MahjongInfoEntity.dart';
import 'package:mahjong/page/mahjong/dialog/GameMessage.dart';
import 'package:mahjong/util/CardUtil.dart';
import 'package:mahjong/util/MessageUtils.dart';
import 'package:mahjong/widget/CurrentGameCommons.dart';
import 'package:mahjong/widget/MahjongCommon.dart';
import 'package:provider/provider.dart';
import 'package:mahjong/notify/CurrentUserInfo.dart';
import 'package:mahjong/entity/UserTouchBar.dart';
import 'package:mahjong/entity/UserTask.dart';
import 'package:mahjong/util/AudioPlayUtil.dart';
import 'SwapMahjongWidget.dart';
import 'SwapCard.dart';

/**
 * 
 * 有几个东西不确定   第一 玩家加进来过后    这个位置 怎么分配
 * 第二  服务器发送消息过来后 到底通知那个 widget 更新
 * 
 * 如果我将所有的  用户放进一个map 里面 然后  对应的 是他们的provide  当用户发出指令的时候就去找出它自己对应的provide
 * 
 * 
 * 
 */
class CurrentGameWidget extends StatefulWidget {
  @override
  _CurrentGameWidgetState createState() => _CurrentGameWidgetState();
}

class _CurrentGameWidgetState extends State<CurrentGameWidget> {
  int _selectCardIndex;
  List<int> _selectArray;

  List<int> _barArray;

  // 杠牌提示
  bool _isBarAction;

  // 胡牌提示
  bool _isHuTips;
  AnimationController _swapAnimationController;

  @override
  void initState() {
    super.initState();
    _selectArray = [];
    _barArray = [];
    _isBarAction = false;
    _isHuTips = false;

    exchangeCardStreamController.stream.listen((event) {
      MessageContext messageContext = event as MessageContext;
      if (messageContext.action == MessageAction.EXCHANGE_CARD &&
          messageContext.body != null) {
        _swapAnimationController?.forward();
      }
      Timer(Duration(seconds: 3), () {
        _swapAnimationController?.reverse();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Consumer(builder:
        (BuildContext buildContext, CurrentUserInfo provider, Widget child) {
      var roomProvider = Provider.of<MahjongInfoEntity>(context, listen: false);
      if (provider.userId == null) {
        return Container();
      }
      // 如果打开了  胡牌提示  这里需要赋值
      if (_isHuTips) {
        if (provider.userCards != null && provider.userCards.length > 0) {
          List<int> temp =
              List.from(provider.userCards.map((e) => e.cardId).toList());
          if (_selectCardIndex != null) {
            if (temp.length > _selectCardIndex) {
              temp.removeAt(_selectCardIndex);
            }
          }
          _barArray = Cardutil.huCards(temp);
        }
      }
      bool showCardTips =
          ((_barArray != null && _barArray.length > 1) && _isBarAction) ||
              (_barArray != null && _barArray.length > 0) && _isHuTips;
      // 当用户报叫过后  让用户只能出 可以胡牌的牌
      if (provider.listening) {
        /**
         * 1. 判断用户是否为刚报完叫
         * 如果是的话  就可以出多张牌
         * 2. 判断用户是否已经报叫了  然后摸牌  出牌
         */
        if (provider.callHuCards == null) {
          if (provider.userCards.length % 3 == 2) {
            List<int> needExportCards = Cardutil.checkUserCallCard(
                provider.userCards.map((e) => e.cardId).toList());
            provider.userCards.forEach((e) {
              if (!needExportCards.contains(e.cardId)) {
                e.isClick = false;
              }
            });
          } else {
            provider.userCards.forEach((e) {
              e.isClick = false;
            });
          }
        } else if (provider.callHuCards != null &&
            provider.userCards.length % 3 == 2) {
          List<int> cardTemp = provider.userCards.map((e) => e.cardId).toList();
          if (roomProvider.licensingCard != null &&
              provider.callHuCards != null) {
            Cardutil.removeCard(cardTemp, roomProvider.licensingCard);
            provider.userCards = cardTemp
                .map((e) => MahjongCardEntity(cardId: e, isClick: false))
                .toList();
            provider.userCards.add(MahjongCardEntity(
                cardId: roomProvider.licensingCard, isClick: true));
          }
        } else {
          provider.userCards.forEach((e) {
            e.isClick = false;
          });
        }
      }
      return Stack(
        children: [
          // 头像的位置
          Positioned(
            right: MahjongSystemConst.lrUserHeaderMargin,
            bottom: MahjongSystemConst.bottomHandCardWidth *
                MahjongSystemConst.cardWHScale,
            child: SafeArea(
              key: userLocation[provider.userId].headKey,
              child: MahjongCommon.getUserHeader(provider, huTop: true),
            ),
          ),
          initReading(provider.prepare),
          provider.listening
              ? Positioned(
                  right: MahjongSystemConst.lrUserHeaderMargin,
                  bottom: MahjongSystemConst.bottomHandCardWidth *
                          MahjongSystemConst.cardWHScale +
                      MahjongSystemConst.userHeaderImageHeight,
                  child: SafeArea(
                      child: Image.asset(
                    "images/mahjong/action/CARD_CALL_TIPS.png",
                    height: MahjongSystemConst.actionTipsWidth,
                    width: MahjongSystemConst.actionTipsWidth,
                    fit: BoxFit.cover,
                  )),
                )
              : Container(),
          Positioned(
            right: MahjongSystemConst.lrlrMagin +
                MahjongSystemConst.exportAreaCardWidth *
                    MahjongSystemConst.cardWHScale *
                    2,
            bottom: MahjongSystemConst.bottomHandCardWidth *
                MahjongSystemConst.cardWHScale,
            child: SafeArea(
                child: Material(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10),
                    ),
                    color: _isHuTips
                        ? Colors.grey.withOpacity(0.7)
                        : Colors.grey.withOpacity(0),
                    child: Ink(
                        //设置背景 默认矩形
                        child: InkWell(
                            //水波纹的颜色
                            splashColor: Colors.black,
                            borderRadius:
                                new BorderRadius.all(new Radius.circular(10.0)),
                            child: Container(
                                padding: EdgeInsets.all(5),
                                child: Image.asset(
                                  "images/mahjong/commons/tips.png",
                                  width: ScreenUtil().screenHeight / 16,
                                )),
                            onTap: () {
                              _isHuTips = !_isHuTips;
                              setState(() {});
                            })))),
          ),
          // 出牌的位置
          Positioned(
              top: MahjongSystemConst.btExportMagin,
              left: ScreenUtil().screenWidth / 2 -
                  MahjongSystemConst.exportAreaSize / 2,
              child: MahjongCommon.getUserExportCard(provider)),
          // 手上的牌的位置
          Positioned(
            bottom: 0,
            right: ScreenUtil().screenWidth -
                MahjongSystemConst.lrUserCardMargin +
                (MahjongSystemConst.hasSafe
                    ? 0.0
                    : MahjongSystemConst.bottomHandCardWidth / 2),
            child: SafeArea(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: buildUserCard(
                    provider,
                    checkUserTask(provider.userTask, [
                      MessageAction.EXCHANGE_CARD,
                      MessageAction.DISK_DICE
                    ])),
              ),
            ),
          ),
          // 交换牌的位置
          SwapMahjongWidget(
            swap: provider.swap,
            position: UserPosition.BOTTOM,
          ),
          SwapCard(provider.userSwapCard, (animation) {
            _swapAnimationController = animation;
          }),
          // 操作的位置
          buildDoActionArea(provider),
          buildSendMessage(),
          // 会存在双杠 的情况    如果有双杠的情况 需要弹出窗口
          !showCardTips
              ? Container()
              : Align(
                  alignment: const Alignment(0, 0.2),
                  child: Container(
                    alignment: Alignment.center,
                    width: MahjongSystemConst.bottomHandCardWidth *
                        (_barArray.length + 1),
                    height: MahjongSystemConst.bottomHandCardWidth *
                        MahjongSystemConst.cardWHScale,
                    decoration: BoxDecoration(
                        color: Colors.black.withOpacity(0.5),
                        borderRadius: BorderRadius.circular(5.00)),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: _barArray
                          .map((item) => InkWell(
                              child: _isBarAction
                                  ? CardWidget.buildBottomCard(item,
                                      MahjongSystemConst.bottomHandCardWidth,
                                      isClick: true)
                                  : CardWidget.buildBottomCard(item,
                                      MahjongSystemConst.bottomHandCardWidth),
                              onTap: () {
                                if (_isBarAction) {
                                  MessageContext message = new MessageContext(
                                      action: MessageAction.CARD_BAR);
                                  message.body = item;
                                  if (MessageUtils.sendMessage(
                                      message.toString())) {
                                    _isBarAction = false;
                                    setState(() {
                                      _barArray = [];
                                    });
                                    AudioPlayUtil.playAudioAction(
                                        MessageAction.CARD_BAR);
                                  }
                                } else {
                                  setState(() {
                                    _barArray = [];
                                  });
                                }
                              }))
                          .toList(),
                    ),
                  ),
                ),
          Align(
            alignment: Alignment(0, 0.5),
            child: AnimatedOpacity(
              opacity: (provider.userDoAction != null && provider.showDoAction)
                  ? 1
                  : 0,
              duration: Duration(seconds: 1),
              child: provider.showDoAction
                  ? Image.asset(
                      "images/mahjong/action_tips/" +
                          provider.userDoAction +
                          ".png",
                      height: MahjongSystemConst.actionTipsWidth,
                      width: MahjongSystemConst.actionTipsWidth,
                      fit: BoxFit.cover,
                    )
                  : SizedBox(),
            ),
          ),
        ],
      );
    });
  }

  Widget buildDoActionArea(CurrentUserInfo provider) {
    double actionHeight = MahjongSystemConst.actionHeight;
    List<Widget> result = buildUserTask(provider, actionHeight);
    if (result == null || result.length == 0) {
      return Container();
    }
    return Positioned(
        right: 0,
        bottom: MahjongSystemConst.bottomHandCardWidth *
            MahjongSystemConst.cardWHScale,
        child: SafeArea(
            child: Container(
          height: actionHeight,
          margin: EdgeInsets.only(right: ScreenUtil().screenHeight / 12),
          width: result.length * actionHeight,
          child:
              Row(mainAxisAlignment: MainAxisAlignment.end, children: result),
        )));
  }

  Positioned buildSendMessage() {
    return Positioned(
        top: ScreenUtil().screenHeight / 3 +
            MahjongSystemConst.userHeaderImageHeight +
            MahjongSystemConst.messageIconHeight,
        right: MahjongSystemConst.edgeMargin +
            MahjongSystemConst.userHeaderImageWidth / 2 -
            MahjongSystemConst.messageIconHeight / 2,
        child: SafeArea(
            child: InkWell(
                onTap: () {
                  showDialog<Null>(
                      context: context,
                      barrierDismissible: false,
                      builder: (BuildContext context) {
                        return GameMessage();
                      });
                },
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.black.withOpacity(0.3),
                      border: Border.all(color: Colors.white.withOpacity(0.3)),
                      borderRadius: BorderRadius.circular(15.h)),
                  width: MahjongSystemConst.messageIconHeight,
                  height: MahjongSystemConst.messageIconHeight,
                  padding: EdgeInsets.all(5.h),
                  child: Image.asset("images/mahjong/commons/message.png"),
                ))));
  }

  List<Widget> buildTouchBar(List<UserTouchBar> data) {
    if (data == null) {
      return [];
    } else {
      List<Widget> param = [];
      data.forEach((element) {
        List<Widget> cards = [];
        for (int i = 0, j = element.cards.length; i < j; i++) {
          MahjongCardEntity cardEntity = element.cards[i];
          if (j == 4 && i < j - 1 && element.cardEnum == CardEnum.ANGANG) {
            cardEntity.cardId = null;
            cards.add(CardWidget.buildExportCard(
                cardEntity, MahjongSystemConst.bottomHandCardWidth / 2));
          } else if (j == 4 &&
              i == j - 1 &&
              element.cardEnum == CardEnum.ANGANG) {
            cards.add(CardWidget.buildExportCard(
                cardEntity, MahjongSystemConst.bottomHandCardWidth / 2));
          } else {
            cards.add(CardWidget.buildExportCard(
                cardEntity, MahjongSystemConst.bottomHandCardWidth / 2));
          }
        }
        param.add(Padding(
            padding: EdgeInsets.only(
                right: MahjongSystemConst.bottomHandCardWidth / 2),
            child: Row(
              children: cards,
            )));
      });
      return param;
    }
  }

  /* 
   * 判断用户是否有这个行为
   */

  bool checkUserTask(UserTask task, List<String> action) {
    var result = true;
    if (task == null) {
      return false;
    } else if (task.task != null && action.contains(task.task)) {
      return true;
    } else if (task.taskArray != null && task.taskArray.length > 0) {
      task.taskArray.forEach((element) {
        if (!action.contains(element) && result) {
          result = false;
        }
      });
    }
    return false;
  }

  List<Widget> buildUserTask(CurrentUserInfo provider, double actionHeight) {
    UserTask task = provider.userTask;
    List<MahjongCardEntity> userCard = provider.userCards;
    if (task == null) {
      return [SizedBox()];
    } else if (task.taskArray != null) {
      return List.castFrom(task.taskArray).map((e) {
        if (e == MessageAction.EXPORT_CARD) {
          return SizedBox();
        }
        return gennerAction(e, userCard, provider, actionHeight);
      }).toList();
    } else {
      if (task.task == MessageAction.EXPORT_CARD) {
        return [SizedBox()];
      }
      return [gennerAction(task.task, userCard, provider, actionHeight)];
    }
  }

  Widget gennerAction(String action, List<MahjongCardEntity> userCard,
      CurrentUserInfo provider, double actionHeight) {
    return new Material(
        color: Colors.white.withOpacity(0),
        child: Ink(
            //设置背景 默认矩形
            child: InkWell(
          //水波纹的颜色
          splashColor: Colors.black,
          borderRadius: new BorderRadius.all(new Radius.circular(10.0)),
          child: Image.asset(
            "images/mahjong/action/" + action + ".png",
            width: actionHeight,
          ),
          onTap: () {
            var userProvider =
                Provider.of<CurrentUserInfo>(context, listen: false);
            MessageContext message = new MessageContext(action: action);
            if (action == MessageAction.USER_PREPARE) {
              userProvider.updatePrepare();
            }
            // 需要出一张  以及 不需要出一张
            if (action == MessageAction.CARD_CALL) {
              userProvider.listening = true;
              // 需要出一张的情况
              if (userCard.length % 3 == 2) {
                List<int> needExportCards = Cardutil.checkUserCallCard(
                    userProvider.userCards.map((e) => e.cardId).toList());
                userProvider.userCards.forEach((e) {
                  if (!needExportCards.contains(e.cardId)) {
                    e.isClick = false;
                  }
                });
              } else {
                userProvider.userCards.forEach((e) {
                  e.isClick = false;
                });
              }
            }
            if (action == MessageAction.EXPORT_CARD &&
                _selectCardIndex == null) {
              return;
            }
            if (action == MessageAction.EXPORT_CARD &&
                _selectCardIndex != null) {
              exportUserCard(userCard, _selectCardIndex, provider.listening);
              return;
            }
            if (action == MessageAction.CARD_BAR) {
              List<int> cardTouchBar = [];
              if (provider.userTouchBar != null &&
                  provider.userTouchBar.length > 0) {
                provider.userTouchBar.forEach((item) {
                  item.cards.forEach((card) {
                    if (item.cardEnum == CardEnum.TOUCH) {
                      cardTouchBar.add(card.cardId);
                    }
                  });
                });
              }
              cardTouchBar.addAll(userCard.map((e) => e.cardId).toList());
              List<int> result = Cardutil.checkCardNumber(cardTouchBar, 4);
              _barArray = result;
              if (_barArray != null && _barArray.length > 1) {
                _isBarAction = true;
                _isHuTips = false;
                userProvider.cleanTask();
                setState(() {});
                return;
              }
            } else if (action == MessageAction.EXCHANGE_CARD) {
              if (_selectArray.length != 3) {
                return;
              } else {
                List<int> selectCard = [];
                for (int i = 0; i < _selectArray.length; i++) {
                  selectCard.add(userCard[_selectArray[i]].cardId);
                }
                message.body = selectCard.join(",");
              }
            }
            if (MessageUtils.sendMessage(message.toString())) {
              if (action == MessageAction.EXCHANGE_CARD) {
                userProvider.exchangeCard(_selectArray);
                this._selectArray = [];
                return;
              }
              AudioPlayUtil.playAudioAction(action);
              provider.showAction(action);
              userProvider.cleanTask();
            }
          },
        )));
  }

  Map<int, int> checkSelectArrayLength(
      List<int> selectArray, List<MahjongCardEntity> userCard) {
    Map<int, int> dataGroup = {};
    List<int> data = [];
    for (int i = 0; i < selectArray.length; i++) {
      data.add(userCard[selectArray[i]].cardId);
    }
    data.forEach((item) {
      if (item >= 1 && item <= 9) {
        cardCheckGroup(dataGroup, 1, item);
      } else if (item >= 10 && item <= 18) {
        cardCheckGroup(dataGroup, 2, item);
      } else {
        cardCheckGroup(dataGroup, 3, item);
      }
    });
    return dataGroup;
  }

  void cardCheckGroup(Map<int, int> dataGroup, int type, data) {
    if (dataGroup[type] == null) {
      dataGroup[type] = 1;
    } else {
      dataGroup[type] = dataGroup[type] + 1;
    }
  }

  /**
   * 注意这里最后一个的位置 如果是 玩家出牌  那么最后一个应该退出来一个
   */

  List<Widget> buildUserCard(CurrentUserInfo provider, bool isChange) {
    List<Widget> touchBar = buildTouchBar(provider.userTouchBar);
    List<MahjongCardEntity> cards = provider.userCards;
    List<Widget> result = [];
    result.addAll(touchBar);
    for (int i = 0; i < cards.length; i++) {
      bool last = (i == cards.length - 1 && cards.length % 3 == 2);
      if (last) {
        result.add(SizedBox(width: MahjongSystemConst.bottomHandCardWidth / 2));
      }
      bool padingTag = false;
      if (isChange) {
        padingTag = _selectArray.indexOf(i) != -1;
      } else {
        padingTag = (_selectCardIndex != null && _selectCardIndex == i);
      }
      result.add(
        Draggable(
          child: InkWell(
            onTap: () {
              if (provider.listening &&
                  checkUserTask(provider.userTask, [MessageAction.CARD_HU])) {
                return;
              }
              if (!cards[i].isClick) {
                return;
              }
              if (isChange) {
                if (_selectArray.indexOf(i) != -1) {
                  _selectArray.remove(i);
                } else if (_selectArray.length == 3 &&
                    _selectArray.indexOf(i) == -1) {
                  _selectArray.removeAt(0);
                  _selectArray.add(i);
                } else {
                  _selectArray.add(i);
                }
                if (checkSelectArrayLength(_selectArray, cards).length > 1) {
                  _selectArray = [_selectArray.last];
                }
              } else {
                if (_selectCardIndex == i && _selectCardIndex != null) {
                  if (!isChange) {
                    exportUserCard(cards, i, provider.listening);
                  }
                } else {
                  _selectCardIndex = i;
                  provider.updateHighlight(cards[i].cardId);
                  if (_isHuTips) {
                    List<int> temp =
                        List.from(cards.map((e) => e.cardId).toList());
                    if (_selectCardIndex != null) {
                      temp.removeAt(_selectCardIndex);
                    }
                    _barArray = Cardutil.huCards(temp);
                    setState(() {});
                  }
                }
              }
              setState(() {});
            },
            child: CardWidget.buildBottomCard(
                cards[i].cardId, MahjongSystemConst.bottomHandCardWidth,
                isClick: cards[i].isClick,
                margin: padingTag
                    ? EdgeInsets.only(
                        bottom: MahjongSystemConst.bottomHandCardWidth / 2)
                    : EdgeInsets.only()),
          ),
          feedback: CardWidget.buildBottomCard(
              cards[i].cardId, MahjongSystemConst.bottomHandCardWidth,
              isClick: cards[i].isClick),
          onDraggableCanceled: (Velocity velocity, Offset offset) {
            if (offset.dy < ScreenUtil().screenHeight / 3 * 2 &&
                cards.length % 3 == 2 &&
                checkUserTask(provider.userTask, [MessageAction.EXPORT_CARD])) {
              exportUserCard(cards, i, provider.listening);
            }
          },
        ),
      );
    }
    if (provider.win) {
      result.add(SizedBox(width: MahjongSystemConst.bottomHandCardWidth / 2));
      result.add(Padding(
        child: CardWidget.buildExportCard(
            MahjongCardEntity(cardId: provider.huCard),
            MahjongSystemConst.bottomHandCardWidth *
                MahjongSystemConst.cardMinWHScale),
        padding: EdgeInsets.only(),
      ));
    }
    if (cards.length % 3 != 2 && !provider.win) {
      result.add(SizedBox(width: MahjongSystemConst.bottomHandCardWidth / 2));
      result.add(SizedBox(width: MahjongSystemConst.bottomHandCardWidth));
    }
    return result;
  }

  Future<void> exportUserCard(
      List<MahjongCardEntity> cards, int index, bool listening) async {
    CurrentUserInfo currentUser =
        Provider.of<CurrentUserInfo>(context, listen: false);
    if (cards.length % 3 == 2) {
      if (!MessageUtils.sendMessage(new MessageContext(
              action: MessageAction.EXPORT_CARD, body: cards[index].cardId)
          .toString())) {
        return;
      }
      AudioPlayUtil.playExportCard(cards[index].cardId);
      currentUser.exportCard(cards[index].cardId);
      currentUser.updateHighlight(null);
      if (listening && currentUser.callHuCards == null) {
        currentUser.callHuCards = Cardutil.checkUserHuCard(
            currentUser.userCards.map((e) => e.cardId).toList());
      }

      if (listening) {
        currentUser.userCards.forEach((item) {
          item.isClick = false;
        });
      }
      diskPartUserProvider.forEach((key, value) {
        if (key != currentUser.userId) {
          value.pervExportUser = false;
          value.updateView();
        }
      });
      _selectCardIndex = null;
      List<int> temp = List.from(cards.map((e) => e.cardId).toList());
      if (_selectCardIndex != null) {
        temp.removeAt(_selectCardIndex);
      }
      _barArray = Cardutil.huCards(temp);
      setState(() {});
    } else {
      _selectCardIndex = null;
      currentUser.updateHighlight(null);
    }
  }

  initReading(bool prepare) {
    return prepare
        ? Positioned(
            right: MahjongSystemConst.lrUserHeaderMargin -
                MahjongSystemConst.userHeaderImageWidth,
            bottom: MahjongSystemConst.bottomHandCardWidth *
                MahjongSystemConst.cardWHScale,
            child: SafeArea(
              child: Container(
                height: MahjongSystemConst.userHeaderImageWidth *
                    MahjongSystemConst.cardMinWHScale,
                width: MahjongSystemConst.userHeaderImageWidth *
                    MahjongSystemConst.cardMinWHScale,
                child: Image.asset(
                  "images/mahjong/commons/reading.png",
                  fit: BoxFit.contain,
                ),
              ),
            ))
        : SizedBox();
  }
}
